﻿/*
 * Licensed to Apereo under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Apereo licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a
 * copy of the License at:
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

using System;
using System.Collections.Generic;

namespace DotNetCasClient.State
{
    /// <summary>
    /// IServiceTicketManager defines the core contract that a ticket manager must implement in 
    /// order to support the CAS client features which require server-side state tracking.
    /// </summary>
    /// <author>Scott Holodak</author>
    public interface IServiceTicketManager
    {
        /// <summary>
        /// You retrieve CasAuthentication properties in the constructor or else you will cause 
        /// a StackOverflow.  CasAuthentication.Initialize() will call Initialize() on all 
        /// relevant controls when its initialization is complete.  In Initialize(), you can 
        /// retrieve properties from CasAuthentication.
        /// </summary>
        void Initialize();

        /// <summary>
        /// Removes expired entries from the ticket store
        /// </summary>
        void RemoveExpiredTickets();

        /// <summary>
        /// Retrieve a CasAuthenticationTicket from the ticket store 
        /// by it's CAS Service Ticket
        /// </summary>
        /// <param name="serviceTicket">The service ticket generated by the CAS server</param>
        /// <returns>The CasAuthenticationTicket or null if no matching ticket is found</returns>
        /// <exception cref="ArgumentNullException">serviceTicket is null</exception>
        /// <exception cref="ArgumentException">serviceTicket is empty</exception>
        CasAuthenticationTicket GetTicket(string serviceTicket);

        /// <summary>
        /// Inserts a CasAuthenticationTicket to the ticket store with a corresponding 
        /// ticket expiration date.
        /// </summary>
        /// <param name="casAuthenticationTicket">The CasAuthenticationTicket to insert</param>
        /// <param name="expiration">The date and time at which the ticket expires</param>
        /// <exception cref="ArgumentNullException">casAuthenticationTicket is null</exception>
        void InsertTicket(CasAuthenticationTicket casAuthenticationTicket, DateTime expiration);

        /// <summary>
        /// Updates the expiration date and time for an existing ticket.  If the ticket does
        /// not exist in the ticket store, just return (do not throw an exception).
        /// </summary>
        /// <param name="casAuthenticationTicket">The CasAuthenticationTicket to insert</param>
        /// <param name="newExpiration">The new expiration date and time</param>
        /// <exception cref="ArgumentNullException">casAuthenticationTicket is null</exception>
        void UpdateTicketExpiration(CasAuthenticationTicket casAuthenticationTicket, DateTime newExpiration);

        /// <summary>
        /// Removes the ticket from the collection if it exists.  If the ticket does not
        /// exist in the ticket store, just return (do not throw an exception).
        /// </summary>
        /// <param name="serviceTicket">The ticket to remove from the ticket store</param>
        /// <exception cref="ArgumentNullException">serviceTicket is null</exception>
        /// <exception cref="ArgumentException">serviceTicket is empty</exception>
        void RevokeTicket(string serviceTicket);

        /// <summary>
        /// Indicates whether or not the ticket store contains the supplied serviceTicket
        /// </summary>
        /// <param name="serviceTicket">The service ticket to check for</param>
        /// <returns>True if the ticket is contained in the store</returns>
        /// <exception cref="ArgumentNullException">serviceTicket is null</exception>
        /// <exception cref="ArgumentException">serviceTicket is empty</exception>
        bool ContainsTicket(string serviceTicket);

        /// <summary>
        /// Revoke all tickets corresponding to the supplied NetId.
        /// </summary>
        /// <param name="netId">The NetId to revoke tickets for</param>
        /// <exception cref="ArgumentNullException">The netId supplied is null</exception>
        /// <exception cref="ArgumentException">The netId supplied is empty</exception>
        void RevokeUserTickets(string netId);

        /// <summary>
        /// Retrieves all tickets in the ticket store that have not already expired.
        /// </summary>
        /// <returns>An enumerable collection of CasAuthenticationTickets</returns>
        IEnumerable<CasAuthenticationTicket> GetAllTickets();

        /// <summary>
        /// Retrieves all non-expired tickets in the ticket store associated with the 
        /// netId supplied.
        /// </summary>
        /// <param name="netId">The NetId to search the collection for</param>
        /// <returns>An enumerable collection of CasAuthenticationTickets</returns>
        /// <exception cref="ArgumentNullException">netId is null</exception>
        /// <exception cref="ArgumentException">netId is empty</exception>
        IEnumerable<CasAuthenticationTicket> GetUserTickets(string netId);

        /// <summary>
        /// Retrieves all CAS Service Tickets in the ticket store that have not already
        /// expired.
        /// </summary>
        /// <returns>An enumerable collection of service tickets</returns>
        IEnumerable<string> GetAllServiceTickets();

        /// <summary>
        /// Retrieves all non-expired CAS Service Tickets in the ticket store associated 
        /// with the netId supplied.
        /// </summary>
        /// <param name="netId">The netId to search the collection for</param>
        /// <returns>An enumerable collection of service tickets</returns>
        /// <exception cref="ArgumentNullException">netId is null</exception>
        /// <exception cref="ArgumentException">netId is empty</exception>
        IEnumerable<string> GetUserServiceTickets(string netId);

        /// <summary>
        /// Retrieves a list of all users that have non-expired CAS authentication 
        /// tickets.
        /// </summary>
        /// <returns>An enumerable collection of NetId's</returns>
        IEnumerable<string> GetAllTicketedUsers();

        /// <summary>
        /// Verify that the supplied casAuthenticationTicket exists in the ticket store
        /// </summary>
        /// <param name="casAuthenticationTicket">The casAuthenticationTicket to verify</param>
        /// <returns>
        /// True if the ticket exists in the ticket store and the properties of that 
        /// ticket match the properties of the ticket in the ticket store.
        /// </returns>
        bool VerifyClientTicket(CasAuthenticationTicket casAuthenticationTicket);
    }
}
